package co.edu.usbcali.unidad.presentation.backEndBeans;

import co.edu.usbcali.unidad.exceptions.*;
import co.edu.usbcali.unidad.modelo.*;
import co.edu.usbcali.unidad.modelo.dto.VehiculoDTO;
import co.edu.usbcali.unidad.presentation.businessDelegate.BusinessDelegatorView;
import co.edu.usbcali.unidad.utilities.*;
import co.edu.usbcali.unidad.utilities.*;

import com.icesoft.faces.async.render.RenderManager;
import com.icesoft.faces.async.render.Renderable;
import com.icesoft.faces.component.ext.HtmlCommandButton;
import com.icesoft.faces.component.ext.HtmlInputText;
import com.icesoft.faces.component.ext.HtmlSelectOneMenu;
import com.icesoft.faces.component.selectinputdate.SelectInputDate;
import com.icesoft.faces.context.DisposableBean;
import com.icesoft.faces.webapp.xmlhttp.FatalRenderingException;
import com.icesoft.faces.webapp.xmlhttp.PersistentFacesState;
import com.icesoft.faces.webapp.xmlhttp.RenderingException;
import com.icesoft.faces.webapp.xmlhttp.TransientRenderingException;
import com.sun.xml.internal.txw2.TxwException;

import java.math.BigDecimal;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import java.util.Vector;

import javax.faces.convert.Converter;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.DataModel;
import javax.faces.model.SelectItem;


public class VehiculoView extends DataSource implements Renderable,
DisposableBean {
	private HtmlInputText txtVeiColor;
	private HtmlInputText txtVeiMarca;
	private HtmlSelectOneMenu cmbEstCodigo_Estado;
	private HtmlSelectOneMenu cmbTipoVehiculo;
	private HtmlInputText txtPerCedula_Persona;

	private HtmlInputText txtVeiCodigo;
	private SelectInputDate txtVeiAno;
	private HtmlCommandButton btnSave;
	private HtmlCommandButton btnModify;
	private HtmlCommandButton btnDelete;
	private HtmlCommandButton btnClear;
	private boolean renderDataTable;
	private boolean flag = true;
	private RenderManager renderManager;
	private PersistentFacesState state = PersistentFacesState.getInstance();
	private List<Vehiculo> vehiculo;
	private List<VehiculoDTO> vehiculoDTO;
	private List<SelectItem> listEstado = new ArrayList<SelectItem>();
	private List<SelectItem> listVehiculo = new ArrayList<SelectItem>();


	public HtmlSelectOneMenu getCmbEstCodigo_Estado() {
		try {
			List<Estado> list = BusinessDelegatorView.findByCriteriaInEstado(
					null, null, null);
			listEstado.clear();
			listEstado.add(new SelectItem(0, " --Seleccione el Estado-- "));

			for (Estado estado : list) {
				listEstado.add(new SelectItem(estado.getEstCodigo(), estado
						.getEstNombre()));
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
		return cmbEstCodigo_Estado;
	}

	public void setCmbEstCodigo_Estado(HtmlSelectOneMenu cmbEstCodigoEstado) {
		cmbEstCodigo_Estado = cmbEstCodigoEstado;
	}

	public HtmlSelectOneMenu getCmbTipoVehiculo() {
		try {
			List<TipoVehiculo> list = BusinessDelegatorView.findByCriteriaInTipoVehiculo(null, null, null);
			listVehiculo.clear();
			listVehiculo.add(new SelectItem(0, " --Seleccione el Tipo Vehiculo-- "));

			for (TipoVehiculo tipoVehiculo : list) {
				listVehiculo.add(new SelectItem(tipoVehiculo.getTpvCodigo(), tipoVehiculo.getTpvNombre()));
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
		return cmbTipoVehiculo;
	}

	public void setCmbTipoVehiculo(HtmlSelectOneMenu cmbTipoVehiculo) {
		this.cmbTipoVehiculo = cmbTipoVehiculo;
	}

	public List<SelectItem> getListEstado() {
		return listEstado;
	}

	public void setListEstado(List<SelectItem> listEstado) {
		this.listEstado = listEstado;
	}

	public List<SelectItem> getListVehiculo() {
		return listVehiculo;
	}

	public void setListVehiculo(List<SelectItem> listVehiculo) {
		this.listVehiculo = listVehiculo;
	}

	public VehiculoView() {
		super("");
	}

	public String action_clear() {
		txtVeiColor.setValue(null);
		txtVeiColor.setDisabled(true);
		txtVeiMarca.setValue(null);
		txtVeiMarca.setDisabled(true);
		cmbEstCodigo_Estado.setValue(null);
		cmbEstCodigo_Estado.setDisabled(true);
		txtPerCedula_Persona.setValue(null);
		txtPerCedula_Persona.setDisabled(true);
		cmbTipoVehiculo.setValue(null);
		cmbTipoVehiculo.setDisabled(true);
		txtVeiAno.setValue(null);
		txtVeiAno.setDisabled(true);
		txtVeiCodigo.setValue(null);
		txtVeiCodigo.setDisabled(false);
		btnSave.setDisabled(true);
		btnDelete.setDisabled(true);
		btnModify.setDisabled(true);
		btnClear.setDisabled(false);

		return "";
	}

	public void listener_txtId(ValueChangeEvent event) {
		if ((event.getNewValue() != null) && !event.getNewValue().equals("")) {
			Vehiculo entity = null;

			try {
				String veiCodigo = new String(txtVeiCodigo.getValue()
						.toString());
				entity = BusinessDelegatorView.getVehiculo(veiCodigo);
			} catch (Exception e) {
				// TODO: handle exception
			}

			if (entity == null) {
				txtVeiColor.setDisabled(false);
				txtVeiMarca.setDisabled(false);
				cmbEstCodigo_Estado.setDisabled(false);
				txtPerCedula_Persona.setDisabled(false);
				cmbTipoVehiculo.setDisabled(false);
				txtVeiAno.setDisabled(false);
				txtVeiCodigo.setDisabled(false);
				btnSave.setDisabled(false);
				btnDelete.setDisabled(true);
				btnModify.setDisabled(true);
				btnClear.setDisabled(false);
			} else {
				txtVeiAno.setValue(entity.getVeiAno());
				txtVeiAno.setDisabled(false);
				txtVeiColor.setValue(entity.getVeiColor());
				txtVeiColor.setDisabled(false);
				txtVeiMarca.setValue(entity.getVeiMarca());
				txtVeiMarca.setDisabled(false);
				cmbEstCodigo_Estado.setValue(entity.getEstado().getEstCodigo());
				cmbEstCodigo_Estado.setDisabled(false);
				txtPerCedula_Persona.setValue(entity.getPersona()
						.getPerCedula());
				txtPerCedula_Persona.setDisabled(false);
				cmbTipoVehiculo.setValue(entity.getTipoVehiculo()
						.getTpvCodigo());
				cmbTipoVehiculo.setDisabled(false);
				txtVeiCodigo.setValue(entity.getVeiCodigo());
				txtVeiCodigo.setDisabled(true);
				btnSave.setDisabled(true);
				btnDelete.setDisabled(false);
				btnModify.setDisabled(false);
				btnClear.setDisabled(false);
			}
		}
	}

	public String action_save() {
		try {

			
			
//			String anio = txtVeiAno.getValue().toString();
//			SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
//			Date modelo = sdf.parse(anio);
			//String fecha = (String) txtVeiAno.getValue();
			
			//Date modelo = txtVeiAno.getNavDate();
			String codigo = txtVeiCodigo.getValue().toString();
			String color = txtVeiColor.getValue().toString();
			String marca = txtVeiMarca.getValue().toString();
			String cedula = txtPerCedula_Persona.getValue().toString();
			String estado = cmbEstCodigo_Estado.getValue().toString();
			String tipVeh = cmbTipoVehiculo.getValue().toString();

//			if (modelo.equals("")) {
//				throw new Exception("El modelo debe ser obligatorio");
//			}

			
			if (!Utilities.soloLetras(color)) {
				throw new Exception("El color debe contener ser solo letras"); 
			}
			if (color.trim().equals("")) {
				throw new Exception("El color es obligatorio");
			}
			if (!Utilities.soloNumeros(codigo)) {
				throw new Exception("El codigo debe ser numerico");
			}
			if (codigo.trim().equals("")) {
				throw new Exception("El codigo del vehiculo es obligatorio");
			}
			if (!Utilities.soloLetras(marca)) {
				throw new Exception("La marca debe contener solo letras");
			}
			if (marca.trim().equals("")) {
				throw new Exception("La marca del vehiculo es obligatoria");
			}
			if (!Utilities.soloNumeros(cedula)) {
				throw new Exception("La cedula debe ser numerico");
			}
			if (cedula.trim().equals("")) {
				throw new Exception("La cedula es obligatoria");
			}
			if (estado.trim().equals("")) {
				throw new Exception("Debe elegir un estado");
			}
			if (tipVeh.trim().equals("")) {
				throw new Exception("Debe elegir un tipo de vehiculo");
			}
			BusinessDelegatorView.saveVehiculo(FacesUtils.checkDate(txtVeiAno), codigo, color, marca, estado, cedula, tipVeh);
			FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYSAVED);
			action_clear();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		return "";
	}

	public String action_delete() {
		try {
			BusinessDelegatorView.deleteVehiculo(FacesUtils
					.checkString(txtVeiCodigo));
			FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYDELETED);
			action_clear();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		return "";
	}

	public String action_modify() {
		try {
			String codigo = txtVeiCodigo.getValue().toString();
			String color = txtVeiColor.getValue().toString();
			String marca = txtVeiMarca.getValue().toString();
			String cedula = txtPerCedula_Persona.getValue().toString();
			String estado = cmbEstCodigo_Estado.getValue().toString();
			String tipVeh = cmbTipoVehiculo.getValue().toString();

//			if (modelo.equals("")) {
//				throw new Exception("El modelo debe ser obligatorio");
//			}

			
			if (!Utilities.soloLetras(color)) {
				throw new Exception("El color debe contener ser solo letras"); 
			}
			if (color.trim().equals("")) {
				throw new Exception("El color es obligatorio");
			}
			if (!Utilities.soloNumeros(codigo)) {
				throw new Exception("El codigo debe ser numerico");
			}
			if (codigo.trim().equals("")) {
				throw new Exception("El codigo del vehiculo es obligatorio");
			}
			if (!Utilities.soloLetras(marca)) {
				throw new Exception("La marca debe contener solo letras");
			}
			if (marca.trim().equals("")) {
				throw new Exception("La marca del vehiculo es obligatoria");
			}
			if (!Utilities.soloNumeros(cedula)) {
				throw new Exception("La cedula debe ser numerico");
			}
			if (cedula.trim().equals("")) {
				throw new Exception("La cedula es obligatoria");
			}
			if (estado.trim().equals("")) {
				throw new Exception("Debe elegir un estado");
			}
			if (tipVeh.trim().equals("")) {
				throw new Exception("Debe elegir un tipo de vehiculo");
			}
			BusinessDelegatorView.updateVehiculo(FacesUtils.checkDate(txtVeiAno), codigo, color, marca, estado, cedula, tipVeh);
			FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYSAVED);
			action_clear();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		return "";
	}

	public String action_modifyWitDTO(Date veiAno, String veiCodigo,
			String veiColor, String veiMarca, String estCodigo_Estado,
			String perCedula_Persona, String tpvCodigo_TipoVehiculo)
	throws Exception {
		try {
			BusinessDelegatorView.updateVehiculo(veiAno, veiCodigo, veiColor,
					veiMarca, estCodigo_Estado, perCedula_Persona,
					tpvCodigo_TipoVehiculo);
			renderManager.getOnDemandRenderer("VehiculoView").requestRender();
			FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYMODIFIED);
		} catch (Exception e) {
			// renderManager.getOnDemandRenderer("VehiculoView").requestRender();
			FacesUtils.addErrorMessage(e.getMessage());
			throw e;
		}

		return "";
	}

	public List<Vehiculo> getVehiculo() {
		if (flag) {
			try {
				vehiculo = BusinessDelegatorView.getVehiculo();
				flag = false;
			} catch (Exception e) {
				flag = true;
				FacesUtils.addErrorMessage(e.getMessage());
			}
		}

		return vehiculo;
	}

	public boolean isFlag() {
		return flag;
	}

	public void setVehiculo(List<Vehiculo> vehiculo) {
		this.vehiculo = vehiculo;
	}

	public boolean isRenderDataTable() {
		try {
			if (flag) {
				if (BusinessDelegatorView.findTotalNumberVehiculo() > 0) {
					renderDataTable = true;
				} else {
					renderDataTable = false;
				}
			}

			flag = false;
		} catch (Exception e) {
			renderDataTable = false;
			e.printStackTrace();
		}

		return renderDataTable;
	}

	public DataModel getData() {
		state = PersistentFacesState.getInstance();

		if (onePageDataModel == null) {
			onePageDataModel = new LocalDataModel(pageSize);
		}

		return onePageDataModel;
	}

	/**
	 * This is where the Object data is retrieved from the database and returned
	 * as a list of objects for display in the UI.
	 */
	private DataPage<Vehiculo> getDataPage(int startRow, int pageSize) {
		// Retrieve the total number of objects from the database. This
		// number is required by the DataPage object so the paginator will know
		// the relative location of the page data.
		int totalNumberVehiculo = 0;

		try {
			totalNumberVehiculo = BusinessDelegatorView
			.findTotalNumberVehiculo().intValue();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		// Calculate indices to be displayed in the ui.
		int endIndex = startRow + pageSize;

		if (endIndex > totalNumberVehiculo) {
			endIndex = totalNumberVehiculo;
		}

		try {
			vehiculo = BusinessDelegatorView.findPageVehiculo(sortColumnName,
					sortAscending, startRow, endIndex - startRow);

			// Remove this Renderable from the existing render groups.
			// leaveRenderGroups();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		// Add this Renderable to the new render groups.
		// joinRenderGroups();
		// Reset the dirtyData flag.
		onePageDataModel.setDirtyData(false);
		// This is required when using Hibernate. If the SessionManager is not
		// cleared or closed objects are cached and stale objects will show up
		// in the table.
		// This way, the detached objects are reread from the database.
		// This call is not required with Hibernate, which uses a Query Hint
		// to clear the l2 cache in the DAO.
		flag = true;

		return new DataPage<Vehiculo>(totalNumberVehiculo, startRow, vehiculo);
	}

	public DataModel getDataDTO() {
		state = PersistentFacesState.getInstance();

		if (onePageDataModel == null) {
			onePageDataModel = new LocalDataModelDTO(pageSize);
		}

		return onePageDataModel;
	}

	/**
	 * This is where the Object data is retrieved from the database and returned
	 * as a list of objects for display in the UI.
	 */
	private DataPage<VehiculoDTO> getDataPageDTO(int startRow, int pageSize) {
		// Retrieve the total number of objects from the database. This
		// number is required by the DataPage object so the paginator will know
		// the relative location of the page data.
		int totalNumberVehiculo = 0;

		try {
			totalNumberVehiculo = BusinessDelegatorView
			.findTotalNumberVehiculo().intValue();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		// Calculate indices to be displayed in the ui.
		int endIndex = startRow + pageSize;

		if (endIndex > totalNumberVehiculo) {
			endIndex = totalNumberVehiculo;
		}

		try {
			vehiculo = BusinessDelegatorView.findPageVehiculo(sortColumnName,
					sortAscending, startRow, endIndex - startRow);

			if (Utilities.validationsList(vehiculo)) {
				vehiculoDTO = new ArrayList<VehiculoDTO>();

				for (Vehiculo vehiculoTmp : vehiculo) {
					VehiculoDTO vehiculoDTO2 = new VehiculoDTO();
					vehiculoDTO2.setVeiCodigo(vehiculoTmp.getVeiCodigo()
							.toString());
					vehiculoDTO2.setVeiAno(vehiculoTmp.getVeiAno());
					vehiculoDTO2
					.setVeiColor((vehiculoTmp.getVeiColor() != null) ? vehiculoTmp
							.getVeiColor().toString()
							: null);
					vehiculoDTO2
					.setVeiMarca((vehiculoTmp.getVeiMarca() != null) ? vehiculoTmp
							.getVeiMarca().toString()
							: null);
					vehiculoDTO2.setEstCodigo_Estado((vehiculoTmp.getEstado()
							.getEstCodigo() != null) ? vehiculoTmp.getEstado()
									.getEstCodigo().toString() : null);
					vehiculoDTO2.setPerCedula_Persona((vehiculoTmp.getPersona()
							.getPerCedula() != null) ? vehiculoTmp.getPersona()
									.getPerCedula().toString() : null);
					vehiculoDTO2
					.setTpvCodigo_TipoVehiculo((vehiculoTmp
							.getTipoVehiculo().getTpvCodigo() != null) ? vehiculoTmp
									.getTipoVehiculo().getTpvCodigo()
									.toString()
									: null);
					vehiculoDTO2.setVehiculo(vehiculoTmp);
					vehiculoDTO2.setVehiculoView(this);
					vehiculoDTO.add(vehiculoDTO2);
				}
			}

			// Remove this Renderable from the existing render groups.
			leaveRenderGroups();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		// Add this Renderable to the new render groups.
		joinRenderGroups();
		// Reset the dirtyData flag.
		onePageDataModel.setDirtyData(false);
		// This is required when using Hibernate. If the SessionManager is not
		// cleared or closed objects are cached and stale objects will show up
		// in the table.
		// This way, the detached objects are reread from the database.
		// This call is not required with Hibernate, which uses a Query Hint
		// to clear the l2 cache in the DAO.
		flag = true;

		return new DataPage<VehiculoDTO>(totalNumberVehiculo, startRow,
				vehiculoDTO);
	}

	protected boolean isDefaultAscending(String sortColumn) {
		return true;
	}

	/**
	 * This method is called when a render call is made from the server. Render
	 * calls are only made to views containing an updated record. The data is
	 * marked as dirty to trigger a fetch of the updated record from the
	 * database before rendering takes place.
	 */
	public PersistentFacesState getState() {
		onePageDataModel.setDirtyData();

		return state;
	}

	/**
	 * This method is called from faces-config.xml with each new session.
	 */
	public void setRenderManager(RenderManager renderManager) {
		this.renderManager = renderManager;
	}

	public void renderingException(RenderingException arg0) {
		if (arg0 instanceof TransientRenderingException) {
		} else if (arg0 instanceof FatalRenderingException) {
			// Remove from existing Customer render groups.
			leaveRenderGroups();
		}
	}

	/**
	 * Remove this Renderable from existing uiCustomerBeans render groups.
	 * OnDemandRenderers are named/created using the underlying Customer Number.
	 */
	private void leaveRenderGroups() {
		if (Utilities.validationsList(vehiculoDTO)) {
			for (VehiculoDTO vehiculoTmp : vehiculoDTO) {
				renderManager.getOnDemandRenderer("VehiculoView").remove(this);
			}
		}
	}

	/**
	 * Add this Renderable to the new uiCustomerBeans render groups.
	 * OnDemandRenderers are named/created using the underlying Customer Number.
	 */
	private void joinRenderGroups() {
		if (Utilities.validationsList(vehiculoDTO)) {
			for (VehiculoDTO vehiculoTmp : vehiculoDTO) {
				renderManager.getOnDemandRenderer("VehiculoView").add(this);
			}
		}
	}

	public void dispose() throws Exception {
	}

	public RenderManager getRenderManager() {
		return renderManager;
	}

	public void setState(PersistentFacesState state) {
		this.state = state;
	}

	public HtmlInputText getTxtVeiColor() {
		return txtVeiColor;
	}

	public void setTxtVeiColor(HtmlInputText txtVeiColor) {
		this.txtVeiColor = txtVeiColor;
	}

	public HtmlInputText getTxtVeiMarca() {
		return txtVeiMarca;
	}

	public void setTxtVeiMarca(HtmlInputText txtVeiMarca) {
		this.txtVeiMarca = txtVeiMarca;
	}



	public HtmlInputText getTxtPerCedula_Persona() {
		return txtPerCedula_Persona;
	}

	public void setTxtPerCedula_Persona(HtmlInputText txtPerCedula_Persona) {
		this.txtPerCedula_Persona = txtPerCedula_Persona;
	}



	public SelectInputDate getTxtVeiAno() {
		return txtVeiAno;
	}

	public void setTxtVeiAno(SelectInputDate txtVeiAno) {
		this.txtVeiAno = txtVeiAno;
	}

	public HtmlInputText getTxtVeiCodigo() {
		return txtVeiCodigo;
	}

	public void setTxtVeiCodigo(HtmlInputText txtVeiCodigo) {
		this.txtVeiCodigo = txtVeiCodigo;
	}

	public HtmlCommandButton getBtnSave() {
		return btnSave;
	}

	public void setBtnSave(HtmlCommandButton btnSave) {
		this.btnSave = btnSave;
	}

	public HtmlCommandButton getBtnModify() {
		return btnModify;
	}

	public void setBtnModify(HtmlCommandButton btnModify) {
		this.btnModify = btnModify;
	}

	public HtmlCommandButton getBtnDelete() {
		return btnDelete;
	}

	public void setBtnDelete(HtmlCommandButton btnDelete) {
		this.btnDelete = btnDelete;
	}

	public HtmlCommandButton getBtnClear() {
		return btnClear;
	}

	public void setBtnClear(HtmlCommandButton btnClear) {
		this.btnClear = btnClear;
	}

	public void setRenderDataTable(boolean renderDataTable) {
		this.renderDataTable = renderDataTable;
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}

	public List<VehiculoDTO> getVehiculoDTO() {
		return vehiculoDTO;
	}

	public void setVehiculoDTO(List<VehiculoDTO> vehiculoDTO) {
		this.vehiculoDTO = vehiculoDTO;
	}

	public TimeZone getTimeZone() {
		return java.util.TimeZone.getDefault();
	}

	/**
	 * A special type of JSF DataModel to allow a datatable and datapaginator to
	 * page through a large set of data without having to hold the entire set of
	 * data in memory at once. Any time a managed bean wants to avoid holding an
	 * entire dataset, the managed bean declares this inner class which extends
	 * PagedListDataModel and implements the fetchData method. fetchData is
	 * called as needed when the table requires data that isn't available in the
	 * current data page held by this object. This requires the managed bean
	 * (and in general the business method that the managed bean uses) to
	 * provide the data wrapped in a DataPage object that provides info on the
	 * full size of the dataset.
	 */
	private class LocalDataModel extends PagedListDataModel {
		public LocalDataModel(int pageSize) {
			super(pageSize);
		}

		public DataPage<Vehiculo> fetchPage(int startRow, int pageSize) {
			// call enclosing managed bean method to fetch the data
			return getDataPage(startRow, pageSize);
		}
	}

	private class LocalDataModelDTO extends PagedListDataModel {
		public LocalDataModelDTO(int pageSize) {
			super(pageSize);
		}

		public DataPage<VehiculoDTO> fetchPage(int startRow, int pageSize) {
			// call enclosing managed bean method to fetch the data
			return getDataPageDTO(startRow, pageSize);
		}
	}
}
